L13: Bash skripty - cykly

linux.edumach.cz



1. Příprava

⚠️ Pokud nemáte stažený Git repozitář z lekce "L11: Bash skripty -- echo, proměnné", stáhněte si ho. Postup je hned na začátku.

2. Cyklus for

Skript ~/bash/for.sh vypíše čísla od 1 do 10 včetně:

#!/bin/bash

for ((i=1; i<=10; i++)); do
  echo $i
done

Zjednodušený zápis předchozího cyklu -- skript for2.sh:

#!/bin/bash

for i in {1..10}; do
  echo $i
done

Nebo i takto -- skript for3.sh:

#!/bin/bash

for i in {20..0..2}; do
  echo $i
done

3. Cyklus for II

Cyklus for může do proměnné postupně dosazovat i seznam hodnot:

Čísla -- skript for4.sh:

for d in 10 20 30 40 50
do
  echo $d
done

Znaky/řetězce -- skript for5.sh:

for c in P R A H A Brno
do
  echo $c
done

Seznam souborů -- skript for6.sh:

for f in /etc/passwd /etc/group
do
  echo "Soubor $f ma $(wc -l $f | awk '{print $1}') radku."
done

4. Cyklus for III

V bashi nemusí být cyklus for vždy jen s předem známým počtem opakování. Ukázkový skript for7.sh vypíše všechny soubory v adresáři s příponou .sh:

#!/bin/bash

for file in *.sh
do
  echo $file
done

☝️ Na https://linuxize.com/post/bash-for-loop/ si prostudujte další možnosti. Jsou tam i příklady s příkazy break a continue, které se běžně nepoužívají.

5. Cyklus while

Cyklus while má standardní syntaxi i chování. Bude se opakovat, dokud bude podmínka TRUE (1) - skript while.sh:

#!/bin/bash

cislo=0

while [ $cislo -ne 100 ]
do
  cislo=$(($cislo + 10))# 
  echo $cislo
done

☝️ Na https://linuxize.com/post/bash-while-loop/ jsou další ukázky. Prostudujte je a vyzkoušejte.

6. Další konstrukce

Kromě zde představených rozhodovacích konstrukcí if, elif, else, for a whilebash ještě další:

Poslední dva typy jsou využitelné zejména pro interakci s uživatelem.

7. Cvičení

7.1. 💾 Kontrola vstupních dat (overeni.sh)

Napište skript overeni.sh, který vyzve uživatele, aby zadal své platné uživatelské jméno. Pokud jej zadá správně, vypíše uvítání. Pokud ne, vyzve uživatele znovu.

7.2. 💾 Je zadaný rok přestupný? (rok.sh)

Historie přestupných dnů sahá do starověkého Egypta. Používal se už v roce 238 př. n. l. V Evropě jej zavedl až papež Řehoř XIII. bulou Inter gravissimas v roce 1582. Různé země a církve však zavedly tuto změnu až později. V tomto našem tak zvaném "gregoriánském" kalendáři je vkládán přestupný den každý rok, který je buď dělitelný čtyřmi beze zbytku, avšak s výjimkou celých století nebo je beze zbytku dělitelný 400.

Napište skript rok.sh, který pro zadaný rok vypíše, zda je nebo není přestupný. Bude se vám hodit vzor složeného výrazu, který má v bashi poněkud složitější syntaxi:

((r % 4 == 0) && (r % 100 != 0)) || (r % 400 == 0)

7.3. 💾 Hromadný převod dat do CSV (csv.sh)

Stáhněte a rozbalte podkladové soubory:

$ wget https://www.edumach.cz/files/csv.tar.gz 
$ tar xvfz csv.tar.gz 

(xvfz = extract, verbose, file, zip)

V adresáři csv se nachází 30 souborů s názvy xaa, xab, xac... obsahující fiktivní data osob netradičně oddělených hvězdičkou.

Napište skript csv.sh, který všechny znaky * ve všech souborech adresáře csv nahradí znaky ; (středník). Dále ke každému souboru přidá příponu .csv (xaa.csv, xab.csv, xac.csv...). Obě operace vykoná skript pomocí vhodného cyklu. V jakém pořadí je na vás.

Dále zajistěte, aby opakovaným spouštěním skriptu již nepřidával další příponu (např. xaa.csv.csv, xaa.csv.csv.csv).

7.4. 💾 Filtrovaný výpis souborů (filtr_read.sh)

Stáhněte si a rozbalte podkladové soubory:

$ wget https://www.edumach.cz/files/folders.tar.gz 
$ tar xvfz folders.tar.gz 

V adresáři folders se nachází 198 souborů různých názvů, formátů a velikostí. Napište skript filtr_read.sh, který vypíše názvy souborů a jejich velikosti (v tomto pořadí) jednoho určeného formátu. Ten skript převezme příkazem read.

Ukázka možného výstupu:

file_A.txt 200 
file_B.txt 35
file_C.txt 4
...

Nápověda: Podrobný výpis souborů je "tabulka", kde jsou položky oddělené mezerou. Například awk '{print $2 $3}' vypíše pouze druhý a třetí "sloupec".

7.5. 💾 Filtrovaný výpis souborů (filtr_arg.sh)

Stáhněte si a rozbalte podkladové soubory:

$ wget https://www.edumach.cz/files/folders.tar.gz 
$ tar xvfz folders.tar.gz 

V adresáři folders se nachází 198 souborů různých názvů, formátů a velikostí. Napište skript filtr_arg.sh, který vypíše názvy souborů a jejich velikosti (v tomto pořadí) jednoho určeného formátu. Ten skript převezme jako argument.

Ukázka možného výstupu:

./filtr_arg.sh txt

file_A.txt 200 
file_B.txt 35
file_C.txt 4
...

Nápověda: První argument skriptu je v proměnné $1. Podrobný výpis souborů je "tabulka", kde jsou položky oddělené mezerou - příkaz awk {'print $2 $3'} vypíše pouze druhý a třetí "sloupec".

7.6. 💾 Úklid souborů podle přípony (uklid.sh)

Stáhněte si a rozbalte podkladové soubory:

$ wget https://www.edumach.cz/files/folders.tar.gz 
$ tar xvfz folders.tar.gz 

V adresáři se nachází 198 souborů různých názvů, formátů a velikostí. Napište skript uklid.sh, který přesune všechny soubory z adresáře folders do adresáře ~/uklizeno. V něm je skript roztřídí podle jejich přípony. Příklad: Skript narazí na soubor s příponou .txt. V adresáři ~/uklizeno vytvoří adresář txt a přesune do něj všechny .txt soubory. Takto roztřídí i ostatní soubory.